沒錯,在多數情況下,我們手上的資料都是中文地址,如果要轉變成經緯度目標需要透過一些第三方服務,這邊我們用google 提供的Geocoding API 服務來使用。
那在開始前,先安裝必要的套件,httr可以讓我們使用GET 或POST 去取得資料,json可以用於解析回傳回來的json格式。
#install.packages("httr")
#install.packages("rjson")
library(httr)
library(rjson)
而Geocoding API 使用的格式如下:
https://maps.googleapis.com/maps/api/geocode/json?language=zh-TW&address=台北火車站
可以得出經緯度json結果。
再來,我們便可使用json 去取得經緯度資訊。
lat <- jsonResult$results[[1]]$geometry$location$lat
lng <- jsonResult$results[[1]]$geometry$location$lng
我在input 資料夾中,新增了一個測試資料集address.csv 。
回到R ,我們便可以利用前面的方法取得所有地址的經緯度座標位置,先將撈取經緯度的方法定義成function,另外有一點需要特別注意的是,因為google 的API 有限制問候的頻率,所以我在函式中多加了Sys.sleep(1) 延遲一秒,以避免被block,另外這邊犯離還蠻容易超出google限制而有錯誤,因此建議大家還是去申請API Key 比較不容易出現問題。
getLatLng <- function(address){
urlData <- GET(paste0("https://maps.googleapis.com/maps/api/geocode/json?language=zh-TW&address=", URLencode(address)))
jsonResult <- rjson::fromJSON(rawToChar(urlData$content))
Sys.sleep(1)
if(jsonResult$status != "OK"){
print("Google geocode API Error")
return("error")
}
print("LatLng Got")
lat <<- jsonResult$results[[1]]$geometry$location$lat
lng <<- jsonResult$results[[1]]$geometry$location$lng
return(paste(lat, lng, sep=","))
}
然後引入資料,並使用rowwise() 函式,把每個row 獨立單程一個參數帶入剛剛定義的函式。
address_data = read.csv("input/address.csv", stringsAsFactors=FALSE, header=FALSE)
result <- address_data %>%
rowwise() %>%
mutate(LatLng = getLatLng(V1))
結果如下
然後前幾天教學我們知道separate() 可以用來切割欄位,因此我們可以這樣做。
result <- address_data %>%
rowwise() %>%
mutate(LatLng = getLatLng(V1)) %>%
filter(LatLng!="error") %>%
separate(LatLng, c("Lat", "Lng"), sep=",") %>%
mutate(Lat=as.numeric(Lat), Lng=as.numeric(Lng))
計算結果:
最後,我們把經緯度畫在地圖上就完成囉!
ggmap(google_map) +
geom_point(data=result, aes(x=Lng, y=Lat), colour='red')
ref:
day15原始碼